#include "ForegroundObserver.h"
#include"mtalog.h"
#include "smsmonitor.h"

#define KUidGlobalNote 270561816
#define KUidSelf 0xEEAD5B01

/**
 * Constructor
 * @return - NONE
 * */
CForegroundObserver::CForegroundObserver():CActive(EPriorityStandard), iHandle(0)
{
	
}

/**
 * Destructor
 * @return - NONE
 * */
CForegroundObserver::~CForegroundObserver()
{
	if(iWindowGroup)
	{
		delete iWindowGroup;
		iWindowGroup = NULL;
	}
	Stop();
}

/**
 * Symbian style constructor
 * @return - NONE
 * */
CForegroundObserver* CForegroundObserver::NewL()
{
	CForegroundObserver* self = new(ELeave)CForegroundObserver();
	CleanupStack::PushL(self);
	self->ConstructL();
	CleanupStack::Pop(self);
	return self;
}

/**
 * Second level constructor
 * @return - NONE
 * */
void CForegroundObserver::ConstructL()
{
	User::LeaveIfError( iWsSession.Connect() );
	iWindowGroup = new (ELeave) RWindowGroup ( iWsSession );
	User::LeaveIfError( iWindowGroup->Construct( (TUint32)iWindowGroup, EFalse ) );
	iWindowGroup->SetOrdinalPosition(-1);
	iWindowGroup->EnableReceiptOfFocus(EFalse);
	
	CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC(iWsSession);
	wgName->SetHidden(ETrue);
	wgName->SetWindowGroupName(*iWindowGroup);
	CleanupStack::PopAndDestroy(1); //  wgName
	
	User::LeaveIfError(iWindowGroup->EnableFocusChangeEvents());
	iHandle = iWindowGroup->CaptureKey(8, 0, 0); // C key
	CActiveScheduler::Add(this);
}

/**
 * This function starts the monitoring
 * @return - NONE
 * */
void CForegroundObserver::Start()
{
	if( IsActive() )
		Cancel();

	iWsSession.EventReady(&iStatus);
	SetActive();
}

/**
 * This function stops the monitoring
 * @return - NONE 
 * */
void CForegroundObserver::Stop()
{
	Cancel();
	iWindowGroup->CancelCaptureKey(iHandle);
}

/**
 * This function is called by the platform upon completion of an asynchronous request
 * @return - NONE
 * */
void CForegroundObserver::RunL()
{
	SMSMonitor* monitor = SMSMonitor::GetInstance();
	
	if (iStatus == KErrNone) 
	{
		TWsEvent event;
		iWsSession.GetEvent(event);
		if(monitor->IsNoteDisplayed())
		{
			if (event.Type() == EEventKey)
			{	
				TInt cScanCode = 1;
				if(event.Key()->iScanCode == cScanCode)
				{
					SimulateKey(EStdKeyDevice1);
					monitor->DeleteMessage();
					CAknGlobalNote* note = CAknGlobalNote::NewL();
					CleanupStack::PushL(note);
					note->ShowNoteL(EAknGlobalInformationNote, _L("Deleted!"));
					CleanupStack::PopAndDestroy(note);
					User::After(1000000); // Delay for the note to appear
				}
			}
		}

		TInt windowGroupId = iWsSession.GetFocusWindowGroup();
		iWsSession.SendEventToWindowGroup(windowGroupId, event);
		CApaWindowGroupName* windowGroupName;
		windowGroupName = CApaWindowGroupName::NewLC(iWsSession, windowGroupId);
		CleanupStack::PushL(windowGroupName);
		
		TUid uid = windowGroupName->AppUid(); 
		CleanupStack::PopAndDestroy(1);
		TRAPD( error, ForegroundEventL(uid) );
	}
	if( IsActive() )
		Cancel();

	iWsSession.EventReady(&iStatus);
	SetActive();
}

/**
 * This function is called with the UID of the current foreground application
 * @return - NONE
 * */
void CForegroundObserver::ForegroundEventL(TUid aAppUid)
{
	if(aAppUid.iUid == KUidGlobalNote) // UID of the Global Note
	{
		SimulateKey();
	}
}

/**
 * This function simulates the RED key on the device
 * @return - NONE
 * */
void CForegroundObserver::SimulateKey()
{
	RWsSession wsSession = CCoeEnv::Static()->WsSession();
	TKeyEvent keyEvent;
	keyEvent.iCode = EKeyNo;  //member of TKeyCode
	keyEvent.iScanCode = EStdKeyNo;
	keyEvent.iModifiers = 0;
	keyEvent.iRepeats = 0;
	wsSession.SimulateKeyEvent(keyEvent);
	wsSession.Flush();
}

/**
 * This function simulates the RED key on the device
 * @return - NONE
 * */
void CForegroundObserver::SimulateKey(TInt aScanCode)
{
	TRawEvent lEventDown;
	lEventDown.Set(TRawEvent::EKeyDown, aScanCode);
	UserSvr::AddEvent(lEventDown);
	TRawEvent lEventUp;
	lEventUp.Set(TRawEvent::EKeyUp, aScanCode);
	UserSvr::AddEvent(lEventUp);
}

/**
 * This function is called by the platform to cancel any asynchronous request
 * @return - NONE
 * */
void CForegroundObserver::DoCancel()
{
	iWsSession.EventReadyCancel();
}
